using System;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;

namespace UltimateDefend
{
    public abstract class ILevel
    {
        public enum LevelResult
        { Win, Lose, Playing }

        #region Game Attributes
        protected int m_nTotalGold;         // so vang thu duoc trong man choi
        protected int m_nNumLives;          // tong so mang cho phep trong 1 man choi
        protected int m_nNumCurrentCreeps;  // so creep con lai trong man choi

        protected int m_nNumFootMen;        // so luong foot man
        protected int m_nNumKnights;        // so luong knight
        protected int m_nNumBosses;         // so luong boss

        protected Point[] m_arrArchors;     // duong di trong man choi
        protected int m_nNumAnchors;        // so diem moc trong man choi

        protected int m_nDelay;      // thoi gian tao ra 2 con creep

        public IEnemy[] creeps;             // mang quan ly creeps co trong man choi
        private Thread[] ths;               // mang cac thread cho moi con creep

        protected LevelResult m_gameResult = LevelResult.Playing;    // Ket qua cua man choi khi ket thuc
        #endregion

        #region Map Attributes
        protected int m_sMap;               // ban do man choi
        #endregion

        #region Methods
        /// <summary>
        /// Bat dau man choi bang cach khoi tao cac thread cho moi con creep
        /// </summary>
        public void Start()
        {
            // tong so creep trong man choi
            int total = m_nNumFootMen + m_nNumKnights + m_nNumBosses;
            int i;

            // Khoi tao cac thread dieu khien creep
            ths = new Thread[total];
            for (i = 0; i < total; i++)
            {
                ths[i] = new Thread(new ThreadStart(creeps[i].StartRunning));
                // Creep bat dau chay
                ths[i].Start();

                // Khoang thoi gian giua 2 con creep dc sinh ra
                Thread.Sleep(m_nDelay);


            }
        }

        /// <summary>
        /// Chuyen doi he toa do chuan sang man hinh thiet bi
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void ConvertToFullScreen(int width, int height)
        {
            int x, y;

            for (int i = 0; i < m_nNumAnchors; i++)
            {
                x = width * m_arrArchors[i].X / 100;
                y = height * m_arrArchors[i].Y / 100;
                m_arrArchors[i] = new Point(x, y);
            }
        }

        /// <summary>
        /// Kiem tra dieu kien man choi ket thuc dc chua
        /// </summary>
        /// <returns></returns>
        public void UpdateData()
        {
            if (m_nNumLives == 0)
            {
                m_gameResult = LevelResult.Lose;
                return;
            }

            else if (m_nNumCurrentCreeps == 0)
            {
                m_gameResult = LevelResult.Win;
                return;
            }
        }

        /// <summary>
        /// Huy man choi do thoat game
        /// </summary>
        public void Abort()
        {
            foreach (Thread t in ths)
            {
                t.Abort();
            }
        }

        /// <summary>
        /// g - Mang luu cac creep co trong man choi
        /// </summary>
        public IEnemy[] EnemyGroup
        {
            get { return creeps; }
        }
        /// <summary>
        /// gs - So vang trong man choi
        /// </summary>
        public int Gold
        {
            get { return m_nTotalGold; }
            set { m_nTotalGold = value; }
        }
        /// <summary>
        /// gs - So mang con lai trong man choi
        /// </summary>
        public int Lives
        {
            get { return m_nNumLives; }
            set { m_nNumLives = value; }
        }

        /// <summary>
        /// gs - So creep con lai trong man choi
        /// </summary>
        public int CurrentCreeps
        {
            get { return m_nNumCurrentCreeps; }
            set { m_nNumCurrentCreeps = value; }
        }

        public LevelResult Result
        {
            get { return m_gameResult; }
        }
        #endregion
    }

    public class Level1 : ILevel
    {
        public Level1(System.Xml.XmlTextReader reader)
        {
            ///////////////////////
            // Doc du lieu tu xml
            ///////////////////////
            reader.ReadToFollowing("level");
            // Doc du lieu cho level 1
            if (reader.GetAttribute("id") == "1")
            {
                // doc delay
                reader.ReadToFollowing("delay");
                m_nDelay = int.Parse(reader.ReadString());

                // doc gold
                reader.ReadToFollowing("gold");
                m_nTotalGold = int.Parse(reader.ReadString());

                // doc num lives
                reader.ReadToFollowing("lives");
                m_nNumLives = int.Parse(reader.ReadString());

                // doc footman
                reader.ReadToFollowing("footman");
                m_nNumFootMen = int.Parse(reader.GetAttribute("nums"));

                // doc knight
                reader.ReadToFollowing("knight");
                m_nNumKnights = int.Parse(reader.GetAttribute("nums"));

                // doc boss
                reader.ReadToFollowing("boss");
                m_nNumBosses = int.Parse(reader.GetAttribute("nums"));


                int i;          // temp variable
                // doc anchor points
                if (reader.ReadToFollowing("map"))
                {
                    reader.ReadToFollowing("anchors");
                    m_nNumAnchors = int.Parse(reader.GetAttribute("nums"));

                    m_arrArchors = new Point[m_nNumAnchors];
                    reader.ReadToFollowing("point");

                    int x, y;
                    for (i = 0; i < m_nNumAnchors; i++)
                    {
                        // ;ay 2 gia tri x, y
                        reader.ReadToDescendant("x");
                        x = int.Parse(reader.ReadString());
                        reader.ReadToNextSibling("y");
                        y = int.Parse(reader.ReadString());
                        reader.ReadToFollowing("point");
                        // gan cho anchors[i]
                        m_arrArchors[i] = new Point(x, y);
                    }
                }

                //////////////////////////////
                // Khoi tao danh sach creeps
                //////////////////////////////
                int total = m_nNumFootMen + m_nNumKnights + m_nNumBosses;

                m_nNumCurrentCreeps = total;

                creeps = new IEnemy[total];
                for (i = 0; i < m_nNumFootMen; i++)
                    creeps[i] = new FootMan(m_arrArchors);
                for (; i < m_nNumFootMen+m_nNumKnights; i++)
                    creeps[i] = new HeavyArmor(m_arrArchors);
                for (; i < total; i++)
                    creeps[i] = new Boss1(m_arrArchors);
            }
        }
    }
}